﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Ionic.Zip;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Threading;


namespace AutoUpdate
{
    public partial class FormMain : Form
    {
        public static string szStaupPath = Application.StartupPath.Replace("/", "\\") + "\\";
        string szFilePath = Application.StartupPath.Replace("/", "\\") + "\\FileUpdate.zip";
        string szLinkDownload = "";
        string szAppName = "";
        Thread ThreadExtract;

        public void WriteURL(string url)
        {
            string appPath = Application.StartupPath;
            var configPath = System.IO.Path.Combine(appPath, "url.bin");
            using (var sw = new System.IO.StreamWriter(configPath))
            {
                sw.Write(url);
                sw.Close();
            }
        }

        public string ReadURL()
        {
            string appPath = Application.StartupPath;
            var configPath = System.IO.Path.Combine(appPath, "url.bin");
            if (File.Exists(configPath))
                using (var sr = new System.IO.StreamReader(configPath))
                {
                    var st = sr.ReadToEnd();
                    sr.Close();
                    return st;
                }
            else
            {
                throw new Exception("Không tìm thấy file url.bin");
            }
        }

        public FormMain(String appName)
        {
            InitializeComponent();
            if (string.IsNullOrEmpty(appName))
            {
                MessageBox.Show("Bạn không thể tự khởi động tập tin này được");
                Application.Exit();
            }
            szAppName = appName;
            try
            {
                szLinkDownload = ReadURL();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Text = "AutoUpdate - version " + Application.ProductVersion;
            lbTitle.Text = string.Format(lbTitle.Text, szAppName, GetVersionFile(szStaupPath + szAppName));
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            txtStatus.Text = "Đang tải " + e.ProgressPercentage.ToString() + "%";
        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            try
            {
                //txtTitle.Text = "Đang tiến hành giải nén dữ liệu:";

                progressBar.Value = 0;

                ExtractFile(szFilePath);
            }
            catch (System.Exception ex)
            {
                txtStatus.Text = ex.Message;
            }

        }

        private string GetVersionFile(string szPath)
        {
            try
            {
                progressBar.Visible = false;
                var versionInfo = FileVersionInfo.GetVersionInfo(szPath);
                return versionInfo.ProductVersion;
            }
            catch
            {
                return "Không có file " + szAppName + "! Vui lòng nhấn Update.";
            }
        }

        private string BuildVersion(string szVersion)
        {
            try
            {
                string[] Array = szVersion.Split('.');

                string szVer = "[" + Array[0] + "." + Array[1] + Array[2] + " Build " + Array[3] + "]";

                return szVer;
            }
            catch (System.Exception ex)
            {
                return "[1.00 Build 0]";
            }

        }

        private void ExtractFile(string szUrlFile)
        {
            ThreadExtract = new Thread((ThreadStart)delegate()
            {
                try
                {
                    using (ZipFile zip = ZipFile.Read(szUrlFile))
                    {
                        int i = 0;
                        this.BeginInvoke((ThreadStart)delegate()
                        {
                            progressBar.Maximum = zip.Count;
                        });

                        foreach (ZipEntry e in zip)
                        {
                            i++;

                            this.BeginInvoke((ThreadStart)delegate()
                            {
                                progressBar.Value = i;
                                //txtTitle2.Text = string.Format("Đang tiến hành giải nén dữ liệu ({0}/{1}):", i, zip.Count);
                                txtStatus.Text = "Đang giải nén file " + e.FileName;
                            });
                            if (e.FileName.IndexOf(ApplicationInfo.ProductName) >= 0 ||
                                e.FileName == "Ionic.Zip.dll" ||
                                e.FileName.IndexOf("vshost") >= 0 ||
                                e.FileName.IndexOf("rtf") >= 0 ||
                                e.FileName.IndexOf("xls") >= 0 ||
                                e.FileName.IndexOf("xlsx") >= 0 ||
                                e.FileName.IndexOf("docx") >= 0 ||
                                e.FileName.IndexOf("doc") >= 0)
                                e.Extract(ExtractExistingFileAction.DoNotOverwrite);
                            else
                                e.Extract(ExtractExistingFileAction.OverwriteSilently);
                        }
                    }
                    this.BeginInvoke((ThreadStart)delegate()
                    {
                        //txtTitle2.Text = "Nhấn bắt đầu để chạy chương trình:";
                        txtStatus.Text = "Hoàn tất tải và giải nén phần mềm " + szAppName;
                        //txtTitle.Text = GetVersionFile(szStaupPath + szAppName);
                        btnReCheck.Visible = true;
                        btnUpdate.Enabled = true;
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Có thể đường dẫn không còn tồn tại. Vui lòng liên hệ tác giả để cập nhật. Chi tiết lỗi: " + ex.Message);
                }
                finally
                {
                    FileDelete(szUrlFile);
                }
            });
            ThreadExtract.Start();
        }

        private void FileDelete(string szFilePath)
        {
            File.Delete(szFilePath);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                progressBar.Visible = true;
                btnUpdate.Enabled = false;
                progressBar.Maximum = 100;
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri(szLinkDownload), szFilePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi. Chi tiết: " + ex.Message + ex.StackTrace);
            }
        }

        private void btnExit_Click_1(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnReCheck_Click(object sender, EventArgs e)
        {
            Process.Start(szAppName);
            Application.Exit();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                ThreadExtract.Abort();
            }
            catch (System.Exception ex)
            {
                txtStatus.Text = ex.Message;
            }
        }
    }
}
